﻿namespace ScrumLite.WebUx.Controllers
{
    using System;
    using System.Web;
    using System.Web.Mvc;
    using ScrumLite.Services.Contracts;
    using ScrumLite.Services;
    using ScrumLite.WebUx.Models;
    using System.Collections.Generic;
    using System.Configuration;
    using ScrumLite.Gateways;
    using System.Globalization;
    using System.Collections.ObjectModel;

    public class DeliverablesController : ContextBaseController
    {

        IDeliverablesService deliverableService;
        IRequestsService requestService;

        public DeliverablesController()
            : this(new DeliverablesServiceClient(), new ProjectsServiceClient(), new RequestsServiceClient(), new ProfileServiceClient())
        {
        }

        public DeliverablesController(Services.IDeliverablesService deliverableService, Services.IProjectsService projectService, Services.IRequestsService requestService, IProfileService profileService)
        : base(profileService, projectService)
        {
            this.deliverableService = deliverableService;
            this.requestService = requestService;
        }

        public void New(string projectId)
        {
            string projectName = Projects.GetProjectName(projectId);
            DeliverableViewData data = new DeliverableViewData();

            WorkAreasPickerViewData workAreasPickerVD = new WorkAreasPickerViewData(new Collection<WorkArea>(this.requestService.GetWorkAreas(projectId))) 
            {
                Title = "Choose workAreas for the deliverable.",
                CheckBoxesName = "chkWorkAreas",
                DisplayMode = WorkAreaDisplayModeType.Horizontal,
                ShowFilterButton = false,
            };
            
            data.WorkAreasPickerViewData = workAreasPickerVD;

            //TODO: Read the uri form de configuration
            data.Path = string.Format(CultureInfo.InvariantCulture,"http://svnrepo.scrumlite.org/{0}/managed/engagement/drops/", projectName);

            data.ReleasedOn = DateTime.Today.Date;
            data.ProjectId = projectId;
            data.ProjectName = projectName;
            data.ViewTitle = "Add New Deliverable";

            RenderView("Write", data);
        }

        public void Save(string projectId, string id, DateTime releasedOn, string name, string path)
        {
            char separator = ',';
            Deliverable deliverable;

            string projectName = Projects.GetProjectName(projectId);

            if (Request.Form["chkWorkAreas"]==null)
            {
                DeliverableViewData data;
                WorkAreasPickerViewData workAreasPickerVD;

                if (!String.IsNullOrEmpty(id))
                {
                    deliverable = this.deliverableService.GetDeliverable(id);

                    workAreasPickerVD = new WorkAreasPickerViewData(new Collection<WorkArea>(this.requestService.GetWorkAreas(projectId)), new Collection<WorkArea>(this.deliverableService.GetWorkAreas(deliverable.Id.ToString())))
                    {
                        Title = "Choose workAreas for the deliverable.",
                        CheckBoxesName = "chkWorkAreas",
                        DisplayMode = WorkAreaDisplayModeType.Horizontal,
                        ShowFilterButton = false
                    };

                    data = new DeliverableViewData
                    {
                        Id = deliverable.Id,
                        WorkAreasPickerViewData = workAreasPickerVD,
                        IsDefective = deliverable.IsDefective,
                        Moniker = deliverable.Moniker,
                        Name = name,
                        ProjectId = projectId,
                        ProjectName = projectName,
                        Path = path,
                        ReleasedOn = releasedOn
                    };
                }
                else {
                    workAreasPickerVD = new WorkAreasPickerViewData(new Collection<WorkArea>(this.requestService.GetWorkAreas(projectId))) 
                    {
                        Title = "Choose workAreas for the deliverable.",
                        CheckBoxesName = "chkWorkAreas",
                        DisplayMode = WorkAreaDisplayModeType.Horizontal,
                        ShowFilterButton = false
                    };

                    data = new DeliverableViewData
                    {
                        WorkAreasPickerViewData = workAreasPickerVD,
                        Name = name,
                        ProjectId = projectId,
                        ProjectName = projectName,
                        Path = path,
                        ReleasedOn = releasedOn
                    };
                }

                data.Message = "You must select one or more workAreas for the deliverable.";
                data.ViewTitle = "Add New Deliverable";

                RenderView("Write", data);

                return;
            }

            string[] selectedWorkAreas = Request.Form["chkWorkAreas"].Split(separator);
            List<WorkArea> listWorkAreas = new List<WorkArea>();

            foreach (string item in selectedWorkAreas)
            {                
                listWorkAreas.Add(requestService.GetWorkArea(projectId, new Guid(item)));
            }

            deliverable = new Deliverable()
            {
                ReleasedOn = releasedOn,
                Name = name,
                Url = new Uri(path),
                WorkAreas = listWorkAreas.ToArray()
            };

            if (String.IsNullOrEmpty(id))
            {
                this.deliverableService.Add(projectId, deliverable);
            }
            else
            {
                deliverable.Id = new Guid(id);
                this.deliverableService.Update(projectId, deliverable);
            }
           
            RedirectToAction("List", "Deliverables");
        }

        public Deliverable Get(string idDeliverable)
        {
            return this.deliverableService.GetDeliverable(idDeliverable);
        }

        public void List(string projectId)
        {
            DeliverablesListViewData data = this.getDeliverablesListViewData(projectId);

            // This is the filter
            foreach (WorkArea wArea in data.WorkAreasPickerViewData.WorkAreas)
            {
                bool IsSelected = false;

                foreach (WorkArea wAreaSelected in data.WorkAreasPickerViewData.SelectedWorkAreas)
                {
                    if (wArea.Id == wAreaSelected.Id)
                    {
                        IsSelected = true;
                    }
                }
                if (!IsSelected)
                {
                    data.WorkAreaDeliverables.Remove(wArea.Name);
                }
            }


            data.ViewTitle = "Deliverables";

            RenderView("List", data);
        }

        public void ListByWorkArea(string projectId, string workAreaName)
        {
            DeliverablesListViewData data = this.getDeliverablesListViewData(projectId);

            // In this view I don't need the WorkAreasPicker control
            data.WorkAreasPickerViewData = null;

            List<string> deliverablesToRemove = new List<string>();
            foreach (string wAreaName in data.WorkAreaDeliverables.Keys)
            {
                if (!wAreaName.Equals(Decoder(workAreaName), StringComparison.CurrentCulture))
                {
                    deliverablesToRemove.Add(wAreaName);
                }
            }
            
            foreach(string key in deliverablesToRemove)
            {
                data.WorkAreaDeliverables.Remove(key);
            }

            data.ViewTitle = "Deliverables";

            RenderView("List", data);
        }

        private DeliverablesListViewData getDeliverablesListViewData(string projectId)
        {
            WorkAreasPickerViewData workAreasPickerVD;
            Collection<WorkArea> workAreasCollection = new Collection<WorkArea>(this.requestService.GetWorkAreas(projectId));

            if (Request.Form["chkWorkAreas"] != null)
            {
                char separator = ',';
                string[] selectedWorkAreasID = Request.Form["chkWorkAreas"].Split(separator);

                List<WorkArea> selectedWorkAreas = new List<WorkArea>();
                foreach (string workAreaID in selectedWorkAreasID)
                {
                    selectedWorkAreas.Add(requestService.GetWorkArea(projectId, new Guid(workAreaID)));

                }

                workAreasPickerVD = new WorkAreasPickerViewData(workAreasCollection, new Collection<WorkArea>(selectedWorkAreas.ToArray()));
            }
            else
            {
                workAreasPickerVD = new WorkAreasPickerViewData(workAreasCollection, workAreasCollection);
            }

            workAreasPickerVD.Title = "Choose work areas for filter:";
            workAreasPickerVD.CheckBoxesName = "chkWorkAreas";
            workAreasPickerVD.DisplayMode = WorkAreaDisplayModeType.Horizontal;
            workAreasPickerVD.ShowFilterButton = true;

            Collection<Deliverable> deliverables = new Collection<Deliverable> (this.deliverableService.GetDeliverables(projectId));
            Dictionary<string, List<DeliverableViewData>> workAreas = ConvertToDeliverablesByWorkArea(deliverables);
            DeliverablesListViewData data = new DeliverablesListViewData(deliverables, workAreas);

            data.WorkAreasPickerViewData = workAreasPickerVD;

            data.ProjectName = Projects.GetProjectName(projectId);
            data.ProjectId = projectId;
            return data;
        }

        public void Edit(string projectId, string id)
        {
            Deliverable deliverable = this.deliverableService.GetDeliverable(id);

            WorkAreasPickerViewData workAreasPickerVD = new WorkAreasPickerViewData(new Collection<WorkArea>(this.requestService.GetWorkAreas(projectId)), new Collection<WorkArea>(this.deliverableService.GetWorkAreas(deliverable.Id.ToString())))
            {
                Title = "Choose workAreas for the deliverable.",
                CheckBoxesName = "chkWorkAreas",
                DisplayMode = WorkAreaDisplayModeType.Horizontal,
                ShowFilterButton = false
            };

            DeliverableViewData data = new DeliverableViewData
            {
                Id = deliverable.Id,
                WorkAreasPickerViewData = workAreasPickerVD,
                IsDefective = deliverable.IsDefective,
                Moniker = deliverable.Moniker,
                Name = deliverable.Name,
                ProjectId = projectId,
                ProjectName = Projects.GetProjectName(projectId),
                Path = deliverable.Url.ToString(),
                ReleasedOn = deliverable.ReleasedOn,
                ViewTitle = "Edit Deliverable"
            };

            RenderView("Write", data);
        }

        private static Dictionary<string, List<DeliverableViewData>> ConvertToDeliverablesByWorkArea(Collection<Deliverable> deliverables)
        {
            Dictionary<string, List<DeliverableViewData>> deliverablesByWorkArea = new Dictionary<string, List<DeliverableViewData>>();

            foreach (Deliverable deliverable in deliverables)
            {                                                
                if (deliverable.WorkAreas != null)
                {
                    foreach (WorkArea workArea in deliverable.WorkAreas)
                    {
                        if (!deliverablesByWorkArea.ContainsKey(workArea.Name))
                        {
                            deliverablesByWorkArea.Add(workArea.Name, new List<DeliverableViewData>());
                        }

                        Collection<WorkArea> workAreasCollection = new Collection<WorkArea>(deliverable.WorkAreas);
                        DeliverableViewData deliverableViewData = new DeliverableViewData(workAreasCollection);
                        deliverableViewData.ReleasedOn = deliverable.ReleasedOn;
                        deliverableViewData.Id = deliverable.Id;
                        deliverableViewData.Moniker = deliverable.Moniker;
                        deliverableViewData.Name = deliverable.Name;
                        deliverableViewData.IsDefective = deliverable.IsDefective;

                        if (deliverable.IsDefective)
                        {
                            deliverableViewData.Path = string.Format(CultureInfo.InvariantCulture,"javascript:__showMessage('{0}')", deliverable.Url.ToString());
                        }
                        else
                        {
                            deliverableViewData.Path = deliverable.Url.ToString();
                        }
                        
                        deliverablesByWorkArea[workArea.Name].Add(deliverableViewData);
                    }
                }
            }

            return deliverablesByWorkArea;
        }

    }
}
